package com.example.gulimall.member.service.impl;

import cn.hutool.core.util.PhoneUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.common.constant.BizCodeEnum;
import com.example.common.exception.Assert;
import com.example.common.vo.UserLoginVo;
import com.example.common.vo.UserRegisterVo;
import com.example.gulimall.member.service.MemberLevelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;
import java.util.Objects;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.utils.PageUtils;
import com.example.common.utils.Query;

import com.example.gulimall.member.dao.MemberDao;
import com.example.common.entity.member.MemberEntity;
import com.example.gulimall.member.service.MemberService;


@Slf4j
@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired private MemberLevelService memberLevelService;
    @Autowired private PasswordEncoder passwordEncoder;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void register(UserRegisterVo userRegisterVo)  {

        MemberEntity entity = new MemberEntity();
        // 设置默认等级
        entity.setLevelId(memberLevelService.getDefaultLevel());

        // 检查手机号 用户名是否唯一
        this.checkPhone(userRegisterVo.getPhone());
        this.checkUserName(userRegisterVo.getUserName());

        entity.setMobile(userRegisterVo.getPhone());
        entity.setUsername(userRegisterVo.getUserName());

        // 密码要加密存储
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        entity.setPassword(bCryptPasswordEncoder.encode(userRegisterVo.getPassword()));
        // 其他的默认信息
        entity.setCity("湖南 长沙");
        entity.setCreateTime(new Date());
        entity.setStatus(0);
        entity.setNickname(userRegisterVo.getUserName());
        entity.setBirth(new Date());
        entity.setEmail("xxx@gmail.com");
        entity.setGender(1);
        entity.setJob("JAVA");

        baseMapper.insert(entity);
    }

    @Override
    public String login(UserLoginVo vo) {

        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        log.info("当前用户[{}]进入登录", vo.getUserName());
        log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");

        MemberEntity entity = this.baseMapper.selectOne(
                Wrappers.<MemberEntity>lambdaQuery()
                        .eq(MemberEntity::getUsername, vo.getUserName())
                        .or()
                        .eq(MemberEntity::getMobile, vo.getUserName())
        );

        if (Objects.isNull(entity)) {
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            log.info("当前用户[{}]不存在!", vo.getUserName());
            log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        }
        boolean matches = this.passwordEncoder.matches(vo.getPassword(), entity.getPassword());

        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        log.info("当前用户[{}]验证密码: {}", vo.getUserName(), matches ? "成功" : "失败");
        log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");

        return matches ? JSONObject.toJSONString(entity) : null;
    }

    @Override
    public MemberEntity isRegister(MemberEntity userInfo) {
        MemberEntity entity = this.baseMapper.selectOne(
                Wrappers.<MemberEntity>lambdaQuery()
                        .eq(MemberEntity::getThirdId, userInfo.getThirdId())
                        .eq(MemberEntity::getSourceType, userInfo.getSourceType())
        );

        if (Objects.isNull(entity)) {
            this.baseMapper.insert(userInfo);
            return userInfo;
        }

        return entity;
    }

    private void checkUserName(String userName) {
        Integer count = this.baseMapper.selectCount(
                Wrappers.<MemberEntity>lambdaQuery()
                        .eq(MemberEntity::getUsername, userName)
        );
        Assert.isMinus(count, BizCodeEnum.USER_EXIST_EXCEPTION);
    }

    private void checkPhone(String phone) {
        Assert.isTrue(PhoneUtil.isMobile(phone), BizCodeEnum.PHONE_FORMAT_EXCEPTION);
        Integer count = this.baseMapper.selectCount(
                Wrappers.<MemberEntity>lambdaQuery()
                        .eq(MemberEntity::getMobile, phone)
        );
        Assert.isMinus(count, BizCodeEnum.PHONE_EXIST_EXCEPTION);
    }


}